package de.jmda.mproc.swingui;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.log4j.Logger;

import de.jmda.gui.swing.mvc.ModelBase;

public class JPanelVisualProcessorConfigurationModel
    extends ModelBase
{
	@XmlRootElement
	private static class LaunchAnnotationProcessingConfigurations
	{
		@XmlElementWrapper
		@XmlElements
		(
				@XmlElement(name="launchAnnotationProcessingModel")
		)
		private List<JPanelVisualProcessorModel>
				launchAnnotationProcessingModels =
						new LinkedList<JPanelVisualProcessorModel>();
	}
	
	private final static Logger LOGGER =
			Logger.getLogger(
					JPanelVisualProcessorConfigurationModel.class);

	private final static File DEFAULT_CONFIG_FILE =
			new File("./LaunchAnnotationProcessingConfigurations.xml");

	private final static Marshaller MARSHALLER;
	private final static Unmarshaller UNMARSHALLER;

	private File configFile;
	
	private LaunchAnnotationProcessingConfigurations
			launchAnnotationProcessingConfigurations =
					new LaunchAnnotationProcessingConfigurations();

	static
	{
		try
    {
			JAXBContext jaxbContext;
	    
	    jaxbContext = JAXBContext.newInstance(
	    		LaunchAnnotationProcessingConfigurations.class);
			
			MARSHALLER = jaxbContext.createMarshaller();
			
			MARSHALLER.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			
			UNMARSHALLER = jaxbContext.createUnmarshaller();
    }
    catch (JAXBException e)
    {
    	throw new ExceptionInInitializerError("failure initialising JAXB\n" + e);
    }
	}

  public JPanelVisualProcessorConfigurationModel()
	{
		super();
		
		configFile = DEFAULT_CONFIG_FILE;

		init();
	}

  public JPanelVisualProcessorConfigurationModel(File configFile)
	{
		super();

		if (configFile.exists() == false)
		{
			JOptionPane.showMessageDialog(
					new JFrame(),
					configFile + " does not exist, using default " + this.configFile);
			this.configFile = DEFAULT_CONFIG_FILE;
		}
		else
		{
			this.configFile = configFile;
		}

		init();
	}
  
  /**
   * This constructor comes handy for testing.
   *
   * @param launchAnnotationProcessingConfigurations
   */
  JPanelVisualProcessorConfigurationModel(
  		List<JPanelVisualProcessorModel>
  				launchAnnotationProcessingModels)
	{
		super();
		this.launchAnnotationProcessingConfigurations.launchAnnotationProcessingModels =
				launchAnnotationProcessingModels;
	}

  private void init()
  {
  	if (configFile == null)
  	{
  		// called from default constructor
  		configFile = DEFAULT_CONFIG_FILE;
  	}
  	
  	if (configFile.exists())
  	{
  		try
      {
        launchAnnotationProcessingConfigurations =
        		(LaunchAnnotationProcessingConfigurations)
        				UNMARSHALLER.unmarshal(configFile);
      }
      catch (JAXBException e)
      {
      	LOGGER.error(
      			"failure unmarshalling from " + configFile.getAbsolutePath(), e);
      }
  	}
  	else
  	{
  		LOGGER.info(
  				"configuration file " + configFile.getAbsolutePath() +
  				" not available");
  	}
  }
  
  public void save()
  {
  	try
    {
	    MARSHALLER.marshal(launchAnnotationProcessingConfigurations, configFile);
    }
    catch (JAXBException e)
    {
    	LOGGER.error("failure marshalling to " + configFile, e);
    }
  }

  public List<JPanelVisualProcessorModel> getLaunchAnnotationProcessingModels()
  {
  	return
  			launchAnnotationProcessingConfigurations.launchAnnotationProcessingModels;
  }
  
  public static void main(String[] args)
  {
	  JPanelVisualProcessorConfigurationModel
	  		jPanelVisualProcessorConfigurationModel =
	  				new JPanelVisualProcessorConfigurationModel();
	  
	  jPanelVisualProcessorConfigurationModel.save();
	  jPanelVisualProcessorConfigurationModel.init();
  }
}